package projet_v1.basics;

import static org.junit.Assert.*;

import java.util.ArrayList;

import org.junit.Before;
import org.junit.Test;

import projet_v1.Actor;
import projet_v1.Breed;
import projet_v1.Human;
import projet_v1.Vampire;
import projet_v1.simulation.Field;
import projet_v1.simulation.Location;

/**
 * Test class of Vampire class.
 * @author Antoine Lavail
 *
 */
public class TestVampire {
    
    private Vampire vampire1;
    private Vampire vampire2;

    /**
     * @throws java.lang.Exception
     */
    @Before
    public void setUp() throws Exception {
        vampire1 = new Vampire(150);
        vampire2 = new Vampire(150, new Field(30,30), new Location(15,15));
    }

    /**
     * Test method for {@link projet_v1.Vampire#encounterCharacter(projet_v1.Character)}.
     */
    @Test(expected=NullPointerException.class)
    public void testEncounterCharacter() {
        
        Human h = new Human(100);
        
        vampire2.encounterCharacter(h);
        assertEquals(100 - 5, h.getHealthPoints());
        assertEquals(Breed.VAMPIRE, h.getLastAttackedBy());
        
        vampire2.setIsThirsty(true);
        vampire2.encounterCharacter(h);        
        assertTrue(h.getHasBeenBitten());
        
        // NullPointerException
        vampire2.encounterCharacter(null);
    }

    /**
     * Test method for {@link projet_v1.Vampire#endOfTurn()}.
     */
    @Test
    public void testEndOfTurn() {
        assertFalse(vampire1.getIsThirsty());
        for (int i = 0; i < 4; i++) {
            vampire1.endOfTurn();
            assertEquals(i+1, vampire1.getDaysThirsty());
            assertFalse(vampire1.getIsThirsty());
        }
        vampire1.endOfTurn();
        assertTrue(vampire1.getIsThirsty());
    }

    /**
     * Test method for {@link projet_v1.Vampire#act(projet_v1.simulation.Field, projet_v1.simulation.Field, java.util.List)}.
     */
    @Test(expected=NullPointerException.class)
    public void testAct() {
        
        Field currentField = new Field(30,30);
        Field updatedField = new Field(30,30);
        
        Human h = new Human(50, new Field(30,30), new Location(14,15));
        currentField.place(vampire2, new Location(15,15));
        currentField.place(h, new Location(14,15));
        updatedField.place(h, new Location(14,15));
        updatedField.place(vampire2, new Location(15,15));
        
        vampire2.act(currentField, updatedField, new ArrayList<Actor>());
        
        assertEquals(50-5, h.getHealthPoints());
        assertEquals(Breed.VAMPIRE, h.getLastAttackedBy());
        
        // NullPointerException's
        vampire2.act(null, new Field(20,20), new ArrayList<Actor>());
        vampire2.act(new Field(20,20), null, new ArrayList<Actor>());
        
    }

    /**
     * Test method for {@link projet_v1.Vampire#Vampire(int)}.
     */
    @Test
    public void testVampireInt() {
        Vampire v = new Vampire(120);
        assertFalse(v.getIsThirsty());
        assertEquals(0, v.getDaysThirsty());
    }

    /**
     * Test method for {@link projet_v1.Vampire#setIsThirsty(boolean)}.
     */
    @Test
    public void testSetIsThirsty() {
        assertFalse(vampire1.getIsThirsty());
        vampire1.setIsThirsty(true);
        assertTrue(vampire1.getIsThirsty());
    }

    /**
     * Test method for {@link projet_v1.Vampire#bite(projet_v1.Human)}.
     */
    @Test(expected=NullPointerException.class)
    public void testBite() {
        
        vampire1.setIsThirsty(true);
        Human h = new Human(100);
        assertFalse(h.getHasBeenBitten());
        vampire1.bite(h);
        assertTrue(h.getHasBeenBitten());
        assertFalse(vampire1.getIsThirsty());
        assertEquals(0, vampire1.getDaysThirsty());
        
        // NullPointerException
        vampire1.bite(null);
    }

}
